import * as THREE from '../../build/three.module.js';
import Stats from '../../jsm/libs/stats.module.js';

import { GLTFLoader } from '../../jsm/loaders/GLTFLoader.js';
import { EffectComposer } from '../../jsm/postprocessing/EffectComposer.js'
import { ShaderPass } from '../../jsm/postprocessing/ShaderPass.js'
import { CopyShader } from '../../jsm/shaders/CopyShader.js';

import { SkinShaderBasic, SkinShaderBeckmann } from '../../jsm/shaders/SkinShader.js';

// 鼠标位置
let mouseX = 0, mouseY = 0;

const halfWindowWidth = innerWidth / 2, halfWindowHeight = innerHeight / 2;

// 网格对象
let mesh;

let firstPass = false;

// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x242a34);

// 相机
const camera = new THREE.PerspectiveCamera(50, innerWidth / innerHeight, 1, 10000);
camera.position.z = 1200;

// 光照
const directionL = new THREE.DirectionalLight(0xffffff);
directionL.position.set(500, 0, 500);
scene.add(directionL);

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
renderer.autoClear = false;
renderer.gammaOutput = true;

// 贝克曼着色器效果，拷贝着色器效果
const effectBeckmann = new ShaderPass(SkinShaderBeckmann);
const effectCopy = new ShaderPass(CopyShader);

const pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
const rtwidth = 512, rtheight = 512;

const composerBeckmann = new EffectComposer( renderer, new THREE.WebGLRenderTarget( rtwidth, rtheight, pars ) );
composerBeckmann.addPass( effectBeckmann );
composerBeckmann.addPass( effectCopy );

// 异步创建网格提
const buildMesh = (geo, scale) => {
  const textureLoader = new THREE.TextureLoader();

  const mapHeight = textureLoader.load('../../models/gltf/LeePerrySmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg'); // 凹凸贴图（高度贴图）
  mapHeight.anisotropy = 4; // 各向异性采样密度，越高会获得越清晰的效果
  mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
  mapHeight.format = THREE.RGBFormat; // jpg 格式的纹理会被加载器默认设置为 RGBFormat;

  const mapSpecular = textureLoader.load('../../models/gltf/LeePerrySmith/Map-SPEC.jpg'); // 高光贴图
  mapSpecular.anisotropy = 4;
  mapSpecular.wrapS = mapSpecular.wrapT = THREE.RepeatWrapping;
  mapSpecular.format = THREE.RGBFormat;

  const mapColor = textureLoader.load('../../models/gltf/LeePerrySmith/Map-COL.jpg'); // 纹理贴图
  mapColor.anisotropy = 4;
  mapColor.wrapS = mapColor.wrapT = THREE.RepeatWrapping;
  mapColor.format = THREE.RGBFormat;

  // 着色器
  const shader = SkinShaderBasic;
  const fragmentShader = SkinShaderBasic.fragmentShader;
  const vertexShader = SkinShaderBasic.vertexShader;
  
  const uniforms = THREE.UniformsUtils.clone(shader.uniforms);

  uniforms['enableBump'].value = true; // 启用凹凸贴图
  uniforms['enableSpecular'].value = true; // 允许高光

  uniforms['tBeckmann'].value = composerBeckmann.renderTarget1.texture; // 贝克曼皮肤着色器贴图
  uniforms['tDiffuse'].value = mapColor; // 漫反射贴图

  uniforms['bumpMap'].value = mapHeight; // 凹凸贴图
  uniforms['specularMap'].value = mapSpecular; // 高光贴图

  uniforms['diffuse'].value.setHex(0xa0a0a0); // 漫反射颜色
  uniforms['specular'].value.setHex(0xa0a0a0); // 高光颜色

  uniforms['uRoughness'].value = 0.2; // 粗糙度
  uniforms['uSpecularBrightness'].value = 0.5; // 高光亮度

  uniforms['bumpScale'].value = 8; // 凹凸度缩放值

  const material = new THREE.ShaderMaterial({
    fragmentShader: fragmentShader,
    vertexShader: vertexShader,
    uniforms: uniforms,
    lights: true
  });
  material.extensions.derivatives = true;

  mesh = new THREE.Mesh(geo, material);
  mesh.position.y = -50;
  mesh.scale.set(scale, scale, scale);

  scene.add(mesh);
}

// 模型几何体
const loader = new GLTFLoader();
loader.load('../../models/gltf/LeePerrySmith/LeePerrySmith.glb', gltf => {
  buildMesh(gltf.scene.children[0].geometry, 100);
});

// 统计
const stats = new Stats();
document.body.appendChild(stats.dom);

// 事件处理
// window Resize 事件
const handleWindowResize = () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);
}
// 鼠标移动
const handleMousemove = e => {
  mouseX = e.clientX - halfWindowWidth;
  mouseY = e.clientY - halfWindowHeight;
}

window.addEventListener('resize', handleWindowResize, false);
document.addEventListener('mousemove', handleMousemove, false);

// 渲染函数
const render = () => {
  const targetX = mouseY * 0.001;
  const targetY = mouseX * 0.001;

  if (mesh) {
    mesh.rotation.y += 0.05 * (targetY - mesh.rotation.y);
    mesh.rotation.x += 0.05 * (targetX - mesh.rotation.x);
  }

  if (firstPass) {
    composerBeckmann.render();
    firstPass = false;
  }

  renderer.render(scene, camera);
}

// 驱动函数
const animate = () => {
  requestAnimationFrame(animate);

  stats.update();
  render();
}
animate();